package com.chatplus.application.service.auth.authentication.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.chatplus.application.common.enumeration.AccountErrorCode;
import com.chatplus.application.common.enumeration.UserTypeEnum;
import com.chatplus.application.domain.entity.account.UserEntity;
import com.chatplus.application.domain.response.AccountLoginResponse;
import com.chatplus.application.service.account.UserService;
import com.chatplus.application.service.auth.authentication.AuthenticationProvider;
import com.chatplus.application.service.auth.authentication.AuthenticationToken;
import com.chatplus.application.service.auth.authentication.SmsCaptchaAuthenticationToken;
import com.chatplus.application.service.verification.PlusCaptchaService;
import com.chatplus.application.service.verification.impl.SmsCaptchaServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import static cn.hutool.core.lang.Assert.isTrue;

/**
 * 手机短信验证码认证器
 */
@Component
public class SmsCaptchaAuthenticationProvider implements AuthenticationProvider {

    private final UserService userService;

    public SmsCaptchaAuthenticationProvider(UserService userService) {
        this.userService = userService;
    }

    @Override
    public String getName() {
        return "短信验证码认证";
    }

    @Override
    public AccountLoginResponse authenticate(AuthenticationToken authenticationToken) {
        checkPhoneNumber(authenticationToken.getUserPrincipal().toString());
        checkSmsVerifyCode(authenticationToken.getUserPrincipal().toString(),
                ((SmsCaptchaAuthenticationToken) authenticationToken).getVerifyCode());
        UserEntity userEntity = userService.getByUsername((String) authenticationToken.getUserPrincipal());
        AccountLoginResponse userAccount = BeanUtil.copyProperties(userEntity, AccountLoginResponse.class);
        userAccount.setUserType(Boolean.TRUE.equals(userEntity.getAdmin()) ? UserTypeEnum.ADMIN_USER : UserTypeEnum.NORMAL_USER);
        //验证账号是否被锁定
        AuthenticationProvider.checkAccountHasLocked(userAccount);
        return null;
    }


    @Override
    public boolean supports(AuthenticationToken authenticationToken) {
        return authenticationToken instanceof SmsCaptchaAuthenticationToken smsCaptchaAuthenticationToken
                && StringUtils.isNotBlank(smsCaptchaAuthenticationToken.getVerifyCode());
    }

    private void checkSmsVerifyCode(String phoneNumber, String verifyCode) {
        PlusCaptchaService smsCaptchaService = SpringUtil.getBean(SmsCaptchaServiceImpl.class);
        boolean check = smsCaptchaService.checkCaptcha(phoneNumber, verifyCode);
        isTrue(check, AccountErrorCode.CAPTCHA_IS_INVALID);
    }

    private void checkPhoneNumber(String phoneNumber) {
        isTrue(PhoneUtil.isMobile(phoneNumber), AccountErrorCode.PHONE_INVALID);
    }

}
